package com.meilai.project.controller.web.business.building;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.meilai.project.dto.CommonResult;
import com.meilai.project.dto.base.ApiResult;
import com.meilai.project.dto.business.building.BuildingAreaDTO;
import com.meilai.project.dto.business.building.BuildingMapExportMPParams;
import com.meilai.project.dto.business.building.DateRangeDTO;
import com.meilai.project.dto.thirdPart.LocationPoint;
import com.meilai.project.dto.thirdPart.TencentADInfo;
import com.meilai.project.dto.thirdPart.TencentIPLocationResult;
import com.meilai.project.dto.thirdPart.TencentIPLocationResultDTO;
import com.meilai.project.mapper.business.building.BuildingAreaTypeMediaTypeRelationMapper;
import com.meilai.project.mapper.other.PCAMapper;
import com.meilai.project.service.business.building.BuildingAreaService;
import com.meilai.project.service.business.media.MediaPointService;
import com.meilai.project.service.other.PCAService;
import com.meilai.project.service.thirdPart.TencentLocationService;
import com.meilai.project.util.IPUtils;
import com.meilai.project.vo.IdNameVO;
import com.meilai.project.vo.business.building.BuildingAreaTypeRelationVO;
import com.meilai.project.vo.business.building.BuildingAreaWebBaseVO;
import com.meilai.project.vo.business.media.MediaTypeExtVO;
import com.meilai.project.vo.business.media.MediaTypeVO;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author 张驰
 * @date 2021/3/15 16:23
 */
@RestController
@RequestMapping("api/web/building")
public class BuildingController {
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    @Autowired
    private PCAService pcaService;
    @Autowired
    private TencentLocationService tencentLocationService;
    @Autowired
    private BuildingAreaService buildingAreaService;
    @Autowired
    private MediaPointService mediaPointService;
    @Autowired
    private PCAMapper pcaMapper;
    @Autowired
    private BuildingAreaTypeMediaTypeRelationMapper buildingAreaTypeMediaTypeRelationMapper;

    @GetMapping("pca_list_by_pid")
    @ApiOperation(value = "省市区")
    public CommonResult pcaListByPid(@RequestParam(value = "pid", required = true) Long pid) {
        return new CommonResult().success(pcaService.pcaList(pid));
    }

    @GetMapping("pc_list_all")
    @ApiOperation(value = "所有省市")
    public CommonResult pcListAll() {
        return new CommonResult().success(pcaService.pcAll());
    }

    @GetMapping("area_list")
    @ApiOperation(value = "根据市code查询区")
    public CommonResult areaByCityCode(@RequestParam(value = "pid", required = true) Long pid) {
        return new CommonResult().success(pcaService.pcaByPid(pid));
    }

    @GetMapping("area_search")
    @ApiOperation(value = "根据区code查询区轮廓经纬度点串")
    public CommonResult areaSearchByAreaCode(@RequestParam(value = "keyword", required = true) String keyword) {
        return new CommonResult().success(tencentLocationService.WSDistrictSearch(keyword));
    }

    @GetMapping("search_address")
    @ApiOperation(value = "查询地址")
    public CommonResult searchAddress(@RequestParam(value = "keyword", required = true) String keyword,
                                      @RequestParam(value = "boundary", required = true) String boundary,
                                      @RequestParam(value = "category", required = false) String category) {
        return new CommonResult().success(tencentLocationService.WSPlaceSearch(keyword, boundary, category));
    }

    @GetMapping("search_address_by_page")
    @ApiOperation(value = "分页查询地址")
    public CommonResult searchAddressByPage(@RequestParam(name = "keyword", required = true) String keyword,
                                            @RequestParam(name = "boundary", required = true) String boundary,
                                            @RequestParam(name = "page", defaultValue = "1") Integer page,
                                            @RequestParam(name = "page_size", defaultValue = "10") Integer page_size,
                                            @RequestParam(name = "category", required = false) String category) {
        return new CommonResult().success(tencentLocationService.WSPlaceSearchPage(keyword, boundary, category, page, page_size));
    }

    @GetMapping("geocoder")
    @ApiOperation(value = "逆地址编码")
    public CommonResult searchAddress(@RequestParam(value = "lat", required = true) BigDecimal lat,
                                      @RequestParam(value = "lng", required = true) BigDecimal lng) {
        return new CommonResult().success(tencentLocationService.WSGeocoder(lat, lng));
    }

    @GetMapping("ip_location")
    @ApiOperation(value = "ip定位")
    public CommonResult ipToLocation(HttpServletRequest request) {
        TencentIPLocationResult returnResult = new TencentIPLocationResult();
        String ip = IPUtils.getIPAddress(request);
        if (ip.equals("127.0.0.1")) {
            returnResult.setStatus(0);
            returnResult.setMessage("query ok");

            TencentIPLocationResultDTO result = new TencentIPLocationResultDTO();
            TencentADInfo adInfo = new TencentADInfo();
            adInfo.setNation("中国");
            adInfo.setProvince("江苏省");
            adInfo.setCity("无锡市");
            adInfo.setDistrict("新吴区");
            adInfo.setAdcode(320214L);
            LocationPoint location = new LocationPoint();
            location.setLat(new BigDecimal("31.475881"));
            location.setLng(new BigDecimal("120.374027"));
            result.setIp("127.0.0.1");
            result.setAd_info(adInfo);
            result.setLocation(location);

            returnResult.setResult(result);
        } else {
            returnResult = JSONObject.parseObject(
                    JSON.toJSONString(tencentLocationService.WSIP(ip)),
                    TencentIPLocationResult.class);
        }
        return new CommonResult().success(returnResult);
    }

    @GetMapping("get_map_center")
    @ApiOperation(value = "获取地图中心")
    public CommonResult getMapCenter(HttpServletRequest request) {
        return new CommonResult().success(buildingAreaService.getMapCenter(request));
    }

    @GetMapping("selectSearchAreaVO")
    @ApiOperation(value = "获取有效地址")
    public CommonResult selectSearchAreaVO() {
        return new CommonResult().success(buildingAreaService.selectSearchAreaVO());
    }

    @GetMapping("get_media_types")
    @ApiOperation(value = "获取点位类型")
    public CommonResult getMediaTypes() {
        return new CommonResult().success(buildingAreaService.getMediaTypes());
    }

    @GetMapping("get_media_types_for_building_type")
    @ApiOperation(value = "获取点位类型，针对项目的分类特化")
    public CommonResult getMediaTypesForBuildingType() {
        return new CommonResult().success(buildingAreaService.getMediaTypesForBuildingType());
    }

    @GetMapping("list_media_types_not_include_gas_station")
    @ApiOperation(value = "获取点位类型(不包括加油站)")
    public ApiResult<MediaTypeVO> getMediaTypesNotIncludeGasStation() {
        return ApiResult.ok(buildingAreaService.getMediaTypesNotIncludeGasStation());
    }

    @GetMapping("list_media_types")
    @ApiOperation(value = "获取点位类型(标识加油站)")
    public ApiResult<MediaTypeExtVO> listMediaTypes() {
        return ApiResult.ok(buildingAreaService.listMediaTypes());
    }

    @GetMapping("list_media_types_of_gas_station")
    @ApiOperation(value = "获取点位类型(加油站)")
    public ApiResult<MediaTypeExtVO> getMediaTypesOfGasStation() {
        return ApiResult.ok(buildingAreaService.getMediaTypesOfGasStation());
    }

    @GetMapping("list_floor_selections")
    public ApiResult<Integer> listFloorSelections() {
        return ApiResult.ok(mediaPointService.listFloorSelections());
    }

    @PutMapping("aline_point_num")
    @ApiOperation(value = "校准点位数量")
    public CommonResult alinePointNum() {
        return new CommonResult().success(buildingAreaService.alinePointNum());
    }

    @PutMapping("aline_point_num_by_id")
    @ApiOperation(value = "校准点位数量")
    public CommonResult alinePointNumById(@RequestParam(name = "id", required = true) Long id) {
        return new CommonResult().success(buildingAreaService.alinePointNum(id));
    }

    @PostMapping("building_area_add")
    @ApiOperation(value = "新增楼盘")
    public CommonResult buildingAreaAdd(@RequestBody BuildingAreaDTO params) {
        if (buildingAreaService.addOne(params)) {
            return new CommonResult().success("新增成功");
        } else {
            return new CommonResult().failed("新增失败");
        }
    }

    @PostMapping("building_area_edit")
    @ApiOperation(value = "编辑楼盘")
    public CommonResult buildingAreaEdit(@RequestBody BuildingAreaDTO params) {
        if (buildingAreaService.editOne(params)) {
            return new CommonResult().success("修改成功");
        } else {
            return new CommonResult().failed("修改失败");
        }
    }

    @PutMapping("building_area_del")
    @ApiOperation(value = "删除楼盘")
    public CommonResult buildingAreaDel(@RequestParam(value = "id", required = true) Long id) {
        if (buildingAreaService.delOne(id)) {
            return new CommonResult().success("删除成功");
        } else {
            return new CommonResult().failed("删除失败");
        }
    }

    @GetMapping("list-all")
    @ApiOperation(value = "查询全部(by ad_code)")
    public ApiResult<BuildingAreaWebBaseVO> listAll(@ApiParam("ad_code") @RequestParam(required = false) String ad_code) {
        return ApiResult.ok(buildingAreaService.listAll(ad_code));
    }

    @GetMapping("list-all-simple")
    @ApiOperation(value = "查询全部只包含id和name(by ad_code)")
    public ApiResult<IdNameVO> listAllSimple(@ApiParam("ad_code") @RequestParam(required = false) String ad_code) {
        return ApiResult.ok(buildingAreaService.listAllSimple(ad_code));
    }

    @GetMapping("list")
    @ApiOperation(value = "列表")
    public CommonResult list(@RequestParam(name = "page", defaultValue = "1") Integer page,
                             @RequestParam(name = "page_size", defaultValue = "10") Integer page_size,
                             @RequestParam(value = "name", required = false) String name,
                             @RequestParam(value = "province", required = false) String province,
                             @RequestParam(value = "city", required = false) String city,
                             @RequestParam(value = "area", required = false) String area,
                             @RequestParam(value = "address", required = false) String address,
                             @RequestParam(value = "adcode", required = false) String adcode,
                             @RequestParam(value = "media_type_spec_ids_str", required = false) String media_type_spec_ids_str) {
        BuildingAreaDTO buildingArea = new BuildingAreaDTO();
        buildingArea.setName(name);
        buildingArea.setProvince(province);
        buildingArea.setCity(city);
        buildingArea.setArea(area);
        buildingArea.setAddress(address);
        buildingArea.setAdcode(adcode);
        if (StringUtils.isNotEmpty(media_type_spec_ids_str)) {
            String[] ids = media_type_spec_ids_str.split(",");
            List<String> idsStrList = Arrays.asList(ids);
            if (CollectionUtils.isNotEmpty(idsStrList)) {
                List<Long> mediaTypeIds = new ArrayList<>();
                List<Long> typeIds = new ArrayList<>();
                List<Long> typeIdsSecond = new ArrayList<>();
                idsStrList.forEach(id -> {
                    String[] temps = id.split("_");
                    if (temps.length >= 1) mediaTypeIds.add(Long.valueOf(temps[0]));
                    if (temps.length >= 2) typeIds.add(Long.valueOf(temps[1]));
                    if (temps.length >= 3) typeIdsSecond.add(Long.valueOf(temps[2]));
                });
                if (CollectionUtils.isNotEmpty(mediaTypeIds)) buildingArea.setMedia_type_ids(mediaTypeIds);
                if (CollectionUtils.isNotEmpty(typeIds)) buildingArea.setType_ids(typeIds);
                if (CollectionUtils.isNotEmpty(typeIdsSecond)) buildingArea.setType_ids_second(typeIdsSecond);
            }
        }
        return new CommonResult().success(buildingAreaService.selectPageList(page, page_size, buildingArea));
    }

    @GetMapping("/one")
    @ApiOperation(value = "获取楼盘信息")
    public CommonResult list(@RequestParam(name = "id") Long id) {
        return new CommonResult().success(buildingAreaService.one(id));
    }

    @GetMapping("list_for_map")
    @ApiOperation(value = "项目地图所用")
    public CommonResult buildingAreaListForMap(@RequestParam(value = "sw_lat", required = true) BigDecimal sw_lat,
                                               @RequestParam(value = "sw_lng", required = true) BigDecimal sw_lng,
                                               @RequestParam(value = "ne_lat", required = true) BigDecimal ne_lat,
                                               @RequestParam(value = "ne_lng", required = true) BigDecimal ne_lng,
                                               @RequestParam(value = "start_at", required = false) String start_at,
                                               @RequestParam(value = "end_at", required = false) String end_at) {
        return new CommonResult().success(buildingAreaService.getListForMap(new LocationPoint(sw_lat, sw_lng), new LocationPoint(ne_lat, ne_lng), new DateRangeDTO(LocalDate.parse(start_at.substring(0, 10), dtf),
                LocalDate.parse(end_at.substring(0, 10), dtf))));
    }

    @GetMapping("detail")
    @ApiOperation(value = "详情")
    public CommonResult detail(@RequestParam(value = "id", required = true) Long id) {
        return new CommonResult().success(buildingAreaService.getDetail(id));
    }

    @GetMapping("get_media_type_id")
    @ApiOperation(value = "获取媒体类型id")
    public CommonResult getMediaTypeId(@RequestParam(value = "building_area_type_id", required = true) Long building_area_type_id) {
        if (building_area_type_id == null) {
            new CommonResult().success();
        }
        return new CommonResult().success(buildingAreaTypeMediaTypeRelationMapper.getMediaTypeId(building_area_type_id));
    }

    @GetMapping("get_media_type_relation")
    @ApiOperation(value = "项目id与点位类型关系信息")
    public CommonResult getMediaTypeRelation() {
        List<Long> buildingAreaTypeIds = buildingAreaTypeMediaTypeRelationMapper.getBuildingAreaTypeIds();
        List<BuildingAreaTypeRelationVO> list1 = new ArrayList<>();
        if (buildingAreaTypeIds.size() > 0) {
            for (Long building_area_type_id : buildingAreaTypeIds) {
                List<Long> list2 = buildingAreaTypeMediaTypeRelationMapper.getMediaTypeIdsByBuildingAreaTypeId(building_area_type_id);
                BuildingAreaTypeRelationVO vo = new BuildingAreaTypeRelationVO();
                vo.setBuilding_area_type_id(building_area_type_id);
                vo.setMedia_type_ids(list2);
                list1.add(vo);
            }
        }
        return new CommonResult().success(list1);
    }

    @PostMapping("/getSelectBuildingIds")
    @ApiOperation("导入楼盘获取选中的楼盘")
    public CommonResult getSelectBuildingIds(@RequestParam("file") MultipartFile file) {
        return new CommonResult().success(buildingAreaService.getSelectBuildingIds(file));
    }

    @GetMapping("/getBuildingImportExcel")
    @ApiOperation("获取导入模板")
    public void getBuildingImportExcel(HttpServletResponse response) {
        buildingAreaService.getBuildingImportExcel(response);
    }

    @PostMapping("map_export_mp")
    @ApiOperation(value = "导出空闲点位数据")
    public ApiResult<String> mapExportMPData(@RequestBody BuildingMapExportMPParams dto) {
        return ApiResult.ok(mediaPointService.exportLeaveUnusedPointExcelAndUploadOSS(dto.getBegin_date().toLocalDate(), dto.getEnd_date().toLocalDate(), dto.getBuilding_ids(), dto.getMedia_type_ids(), false, 3), "导出成功");
    }

    @PostMapping("export_building_media_point_excel")
    @ApiOperation(value = "导出上刊点位Excel")
    public void exportBuildingMediaPointExcel(HttpServletResponse response,
                                              @RequestBody List<Long> building_ids) {
        buildingAreaService.exportBuildingMediaPointExcel(response, building_ids);
    }
}
